package org.suze.demo.aop;

import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.ui.Model;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.suze.framework.base.Result;
import org.suze.framework.base.enums.RemoteEnum;

import javax.servlet.http.HttpServletRequest;

/**
 * @description: 异常拦截器
 * @Date : 2019/3/20 上午10:58
 * @Author : 石冬冬-Seig Heil
 */
@ControllerAdvice
@Slf4j
public class ExceptionInterceptor {
    /**
     * 应用到所有@RequestMapping注解方法，在其执行之前初始化数据绑定器
     * @param binder
     */
    @InitBinder
    public void initBinder(WebDataBinder binder) {}

    /**
     * 把值绑定到Model中，使全局@RequestMapping可以获取到该值
     * @param model
     */
    @ModelAttribute
    public void addAttributes(Model model) {
        model.addAttribute("author", "Magical Sam");
    }


    @ExceptionHandler({NullPointerException.class})
    @ResponseBody
    Result<Object> handleException(NullPointerException e, HttpServletRequest request) {
        log.error("空指针异常 IP:{} {} - {}", request.getMethod(), request.getRequestURI(), e);
        return Result.fail(RemoteEnum.ERROR_IN_RUNTIME, "系统处理异常，请稍后重试!");
    }

    @ExceptionHandler({HttpMediaTypeNotSupportedException.class, HttpMediaTypeNotAcceptableException.class})
    @ResponseBody
    Result<Object> handleException(HttpMediaTypeNotSupportedException e, HttpServletRequest request) {
        log.error("{} {} {}", request.getMethod(), request.getRequestURI(), e.getMessage());
        return Result.fail(RemoteEnum.ERROR_IN_RUNTIME, e.getMessage());
    }

    @ExceptionHandler(org.springframework.beans.TypeMismatchException.class)
    @ResponseBody
    Result<Object> handleException(org.springframework.beans.TypeMismatchException e, HttpServletRequest request) {
        log.warn("{} {} {}", request.getMethod(), request.getRequestURI(), e.getMessage());
        return Result.fail(RemoteEnum.ERROR_IN_RUNTIME, "参数类型错误:" + e.getMessage());
    }

    @ExceptionHandler(DuplicateKeyException.class)
    @ResponseBody
    Result<Object> handleDuplicateKeyException(DuplicateKeyException e, HttpServletRequest request) {
        log.error(request.getMethod() + " " + request.getRequestURI() + " Message:{}", e.getMessage());
        return Result.fail(RemoteEnum.ERROR_IN_RUNTIME, "请勿重复操作!");
    }

    /**
     * 全局异常捕捉处理
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public Result errorHandler(Exception ex) {
        log.error("exception - msg:{}", ex.getMessage(),ex);
        if(ex instanceof RuntimeException){
            return Result.failInRuntime(ex.getMessage());
        }
        return Result.failInServer(ex.getMessage());
    }

}
